package org.support.small.mallms.service;

import com.google.common.hash.Hashing;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.stereotype.Service;
import org.support.small.infrastructure.admin.AdminTokens;
import org.support.small.infrastructure.admin.Admins;
import org.support.small.infrastructure.mapper.AdminTokensMapper;
import org.support.small.infrastructure.mapper.AdminsMapper;
import org.support.small.mallms.exception.I18NCodeException;
import org.support.small.mallms.exception.TokenForbiddenException;
import org.support.small.mallms.utils.RequestContextUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.UUID;

@Service
public class AdminsService {
    @Resource
    private AdminsMapper adminsMapper;

    @Resource
    private AdminTokensMapper adminTokensMapper;

    public String login(String username, String password, HttpServletRequest request) {
        QueryWrapper queryWrapper = QueryWrapper.create().where(Admins::getUsername).eq(username);
        Admins admins = adminsMapper.selectOneByQuery(queryWrapper);
        if (Objects.isNull(admins)) {
            throw I18NCodeException.of("username.is.not.exist");
        }

        String hashCode = Hashing.sha256().hashString(password, Charset.defaultCharset()).toString();
        if (!Objects.equals(admins.getPassword(), hashCode)) {
            throw I18NCodeException.of("password.is.not.match");
        }

        if (!admins.getActive()) {
            throw I18NCodeException.of("admins.not.active");
        }
        // 获取登录浏览器信息
        String userAgent = request.getHeader("User-Agent");

        // 记录登录用户日志
        String token = UUID.randomUUID().toString();
        AdminTokens adminLoginLogs = new AdminTokens();
        adminLoginLogs.setAdminId(admins.getId());
        adminLoginLogs.setUserAgent(userAgent);
        adminLoginLogs.setToken(token);
        adminLoginLogs.setExpiredTime(LocalDateTime.now().plusHours(2));
        adminTokensMapper.insert(adminLoginLogs);
        return token;
    }

    public void checkLogin(@NotNull String token) {
        QueryWrapper queryWrapper = QueryWrapper.create().where(AdminTokens::getToken).eq(token);
        AdminTokens adminLoginLogs = adminTokensMapper.selectOneByQuery(queryWrapper);
        if (Objects.isNull(adminLoginLogs) || adminLoginLogs.getExpiredTime().isBefore(LocalDateTime.now())) {
            throw TokenForbiddenException.of("token.is.expired");
        }

        // 查询当前用户是否存在
        Admins admins = adminsMapper.selectOneById(adminLoginLogs.getAdminId());
        if (Objects.isNull(admins)) {
            throw TokenForbiddenException.of("admins.not.exist");
        }

        if (!admins.getActive()) {
            throw TokenForbiddenException.of("admins.not.active");
        }

        RequestContextUtils.login(admins.getId(), admins.getUsername());
    }
}
